package cc.cocosky.imserver;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

public class MainServer {
	private static final int PORT = 8899;
	private Application application = new Application();
	
	public void start() throws IOException {
		Selector selector = Selector.open();
		ServerSocketChannel serverChannel = ServerSocketChannel.open();
		serverChannel.socket().bind(new InetSocketAddress(PORT));
		serverChannel.configureBlocking(false);
		serverChannel.register(selector, SelectionKey.OP_ACCEPT);
		while(true) {
			selector.select();
			for(Iterator<SelectionKey> it = selector.selectedKeys().iterator(); it.hasNext(); ) {
				SelectionKey key = it.next();
				System.out.println("ops : " + key.readyOps());
				if(key.isReadable()) {
					SocketChannel channel = (SocketChannel) key.channel();
					Session session = application.getSession(channel);
					session.read();
				} else if(key.isAcceptable()) {
					//sun.nio.ch.ServerSocketChannelImpl cannot be cast to java.nio.channels.SocketChannel
					//SocketChannel channel = (SocketChannel) key.channel();
					ServerSocketChannel schannel = (ServerSocketChannel) key.channel();
					SocketChannel channel = schannel.accept();
					if(channel != null) {
						System.out.println("accepted : " + channel.getRemoteAddress());
						application.createSession(channel);
						channel.configureBlocking(false);
						channel.socket().setTcpNoDelay(true);
						channel.register(selector, SelectionKey.OP_READ);
					}
				}
				//若不移除SelectionKey，（如OP_ACCEPT）则下次selector.select()后selector.selectedKeys()集合中仍有该SelectionKey
				it.remove();
			}
		}
		
	}
	
	public static void main(String[] args) throws IOException {
		MainServer server = new MainServer();
		server.start();
	}

}
